Imports System.Text
Imports System.IO

Namespace IO
  ''' <summary>
  ''' File helper functions.
  ''' </summary>
  ''' <remarks></remarks>
  Public NotInheritable Class FileHelper

    'Progress event for the ReadTextFile function
    Shared Event ReadTextFileProgress As EventHandler(Of FileProcessEventArgs)

    ''' <summary>
    ''' Locks a text file and returns content. Also thows the ReadTextFileProgress event.
    ''' </summary>
    ''' <param name="fileName">File name to read.</param>
    ''' <param name="encoding">Text encoding.</param>
    ''' <returns>File contents.</returns>
    ''' <remarks></remarks>
    Shared Function ReadTextFile(ByVal fileName As String, ByVal encoding As System.Text.Encoding) As String
      Dim fileText As New StringBuilder()
      Dim fileBytes As Int32
      Dim fileTotalLength As Long
      Dim fileLenghCopied As Long
      Dim cancel As Boolean

      If String.IsNullOrEmpty(fileName) Then
        Throw New ArgumentNullException("fileName")
      End If

      If IsNothing(encoding) Then
        Throw New ArgumentNullException("encoding")
      End If

      'Open up the file
      Using readFileStream As New FileStream(fileName, FileMode.Open, FileAccess.Read)
        fileTotalLength = readFileStream.Length
        readFileStream.Lock(0, fileTotalLength)

        'Read the first chunk of data
        Dim Data(512) As Byte
        fileBytes = readFileStream.Read(Data, 0, 512)

        'Loop through and read the rest of the data
        While fileBytes > 0
          fileText.Append(encoding.GetString(Data, 0, fileBytes))
          fileLenghCopied += fileBytes
          Dim arguments As New FileProcessEventArgs
          arguments.TotalLength = fileTotalLength
          arguments.LengthCopied = fileLenghCopied
          arguments.Percent = CDbl((fileLenghCopied / fileTotalLength) * 100)
          arguments.Cancel = cancel

          'Send back progress
          RaiseEvent ReadTextFileProgress(Nothing, arguments)

          If cancel Then
            'Clear variable
            fileText.Remove(1, fileText.Length)
            Exit While
          End If

          fileBytes = readFileStream.Read(Data, 0, 512)

        End While

        readFileStream.Unlock(0, fileTotalLength)
        readFileStream.Close()

      End Using

      If Not cancel Then
        Return fileText.ToString()
      Else
        Return String.Empty
      End If

    End Function

    ''' <summary>
    ''' Copies file with overwrite.
    ''' </summary>
    ''' <param name="sourceFileName">Souce file name.</param>
    ''' <param name="destinationFileName">Destination file name.</param>
    ''' <remarks></remarks>
    Overloads Shared Sub CopyFile(ByVal sourceFileName As String, ByVal destinationFileName As String)

      CopyFile(sourceFileName, destinationFileName, True)

    End Sub

    ''' <summary>
    ''' Copies file.
    ''' </summary>
    ''' <param name="sourceFileName">Source file name.</param>
    ''' <param name="destinationFileName">Destination file name.</param>
    ''' <param name="overwrite">Overwrties file.</param>
    ''' <remarks></remarks>
    Overloads Shared Sub CopyFile(ByVal sourceFileName As String, ByVal destinationFileName As String, ByVal overwrite As Boolean)

      My.Computer.FileSystem.CopyFile(sourceFileName, destinationFileName, overwrite)

    End Sub

    ''' <summary>
    ''' Copies file.
    ''' </summary>
    ''' <param name="sourceFileName">Source file name.</param>
    ''' <param name="destinationFileName">Destination file name.</param>
    ''' <param name="showUI">Shows UI during copy process.</param>
    ''' <remarks></remarks>
    Overloads Shared Sub CopyFile(ByVal sourceFileName As String, ByVal destinationFileName As String, ByVal showUI As Microsoft.VisualBasic.FileIO.UIOption)

      My.Computer.FileSystem.CopyFile(sourceFileName, destinationFileName, showUI)

    End Sub

    ''' <summary>
    ''' Copies file.
    ''' </summary>
    ''' <param name="sourceFileName">Source file name.</param>
    ''' <param name="destinationFileName">Destination file name.</param>
    ''' <param name="showUI">Shows UI during copy process.</param>
    ''' <param name="onUserCancel">Allows user to cancel process.</param>
    ''' <remarks></remarks>
    Overloads Shared Sub CopyFile(ByVal sourceFileName As String, ByVal destinationFileName As String, ByVal showUI As Microsoft.VisualBasic.FileIO.UIOption, ByVal onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption)

      My.Computer.FileSystem.CopyFile(sourceFileName, destinationFileName, showUI, onUserCancel)

    End Sub

    ''' <summary>
    ''' Deletes file.
    ''' </summary>
    ''' <param name="file">File name to delete.</param>
    ''' <remarks></remarks>
    Overloads Shared Sub DeleteFile(ByVal file As String)
      My.Computer.FileSystem.DeleteFile(file)
    End Sub

    ''' <summary>
    ''' Deletes file.
    ''' </summary>
    ''' <param name="file">File name to delete.</param>
    ''' <param name="showUI">Shows UI during delete process.</param>
    ''' <param name="recycle">Sends file to recycle bin.</param>
    ''' <remarks></remarks>
    Overloads Shared Sub DeleteFile(ByVal file As String, ByVal showUI As Microsoft.VisualBasic.FileIO.UIOption, ByVal recycle As Microsoft.VisualBasic.FileIO.RecycleOption)
      My.Computer.FileSystem.DeleteFile(file, showUI, recycle)
    End Sub

    ''' <summary>
    ''' Deletes file.
    ''' </summary>
    ''' <param name="file">File name to delete.</param>
    ''' <param name="showUI">Shows UI during delete process.</param>
    ''' <param name="recycle">Sends file to fecyle bin.</param>
    ''' <param name="onUserCancel">Allows user to cancel process.</param>
    ''' <remarks></remarks>
    Overloads Shared Sub DeleteFile(ByVal file As String, ByVal showUI As Microsoft.VisualBasic.FileIO.UIOption, ByVal recycle As Microsoft.VisualBasic.FileIO.RecycleOption, ByVal onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption)
      My.Computer.FileSystem.DeleteFile(file, showUI, recycle, onUserCancel)
    End Sub

    ''' <summary>
    ''' Moves file.
    ''' </summary>
    ''' <param name="sourceFileName">File to move.</param>
    ''' <param name="destinationFileName">Destination file name.</param>
    ''' <remarks></remarks>
    Overloads Shared Sub MoveFile(ByVal sourceFileName As String, ByVal destinationFileName As String)
      MoveFile(sourceFileName, destinationFileName, True)
    End Sub

    ''' <summary>
    ''' Moves file.
    ''' </summary>
    ''' <param name="sourceFileName">File to move.</param>
    ''' <param name="destinationFileName">Destination file name.</param>
    ''' <param name="overwrite">Overwrites destination file name.</param>
    ''' <remarks></remarks>
    Overloads Shared Sub MoveFile(ByVal sourceFileName As String, ByVal destinationFileName As String, ByVal overwrite As Boolean)
      My.Computer.FileSystem.MoveFile(sourceFileName, destinationFileName, overwrite)
    End Sub

    ''' <summary>
    ''' Moves file.
    ''' </summary>
    ''' <param name="sourceFileName">File to move.</param>
    ''' <param name="destinationFileName">Destination file name.</param>
    ''' <param name="showUI">Shows UI during move process.</param>
    ''' <remarks></remarks>
    Overloads Shared Sub MoveFile(ByVal sourceFileName As String, ByVal destinationFileName As String, ByVal showUI As Microsoft.VisualBasic.FileIO.UIOption)
      My.Computer.FileSystem.MoveFile(sourceFileName, destinationFileName, showUI)
    End Sub

    ''' <summary>
    ''' Moves file.
    ''' </summary>
    ''' <param name="sourceFileName">File to move.</param>
    ''' <param name="destinationFileName">Destination file name.</param>
    ''' <param name="showUI">Shows UI during move process.</param>
    ''' <param name="onUserCancel">Allows user to cancel process.</param>
    ''' <remarks></remarks>
    Overloads Shared Sub MoveFile(ByVal sourceFileName As String, ByVal destinationFileName As String, ByVal showUI As Microsoft.VisualBasic.FileIO.UIOption, ByVal onUserCancel As Microsoft.VisualBasic.FileIO.UICancelOption)
      My.Computer.FileSystem.MoveFile(sourceFileName, destinationFileName, showUI, onUserCancel)
    End Sub



    ''' <summary>
    ''' Verifies if a file exists.
    ''' </summary>
    ''' <param name="path">File name to verify.</param>
    ''' <returns>True if file is found.</returns>
    ''' <remarks></remarks>
    Shared Function FileExists(ByVal path As String) As Boolean
      Return My.Computer.FileSystem.FileExists(path)
    End Function

    ''' <summary>
    ''' Finds computer file information.
    ''' </summary>
    ''' <param name="file">File name.</param>
    ''' <returns><seealso cref="FileInformation"/></returns>
    ''' <remarks></remarks>
    Public Shared Function FileInformation(ByVal file As String) As FileInformation
      Dim result As New FileInformation
      Dim serverFile As System.IO.FileInfo = My.Computer.FileSystem.GetFileInfo(file)

      If Not IsNothing(file) Then
        With result
          .Attributes = serverFile.Attributes
          .CreationTime = serverFile.CreationTime
          .DirectoryName = serverFile.DirectoryName
          .Extension = serverFile.Extension
          .FullName = serverFile.FullName
          .IsReadOnly = serverFile.IsReadOnly
          .LastAccessTime = serverFile.LastAccessTime
          .LastWriteTime = serverFile.LastWriteTime
          .Length = serverFile.Length
          .Name = serverFile.Name
        End With
      End If

      Return result

    End Function


    Private Sub New()
    End Sub

  End Class

  ''' <summary>
  ''' Event Arguments for the FileProcess event.
  ''' </summary>
  ''' <remarks></remarks>
  Public Class FileProcessEventArgs
    Inherits System.EventArgs

    Private _totalLength As Long
    ''' <summary>
    ''' Total length of file.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property TotalLength() As Long
      Get
        Return _totalLength
      End Get
      Set(ByVal value As Long)
        _totalLength = value
      End Set
    End Property
    Private _lengthCopied As Long
    ''' <summary>
    ''' Total length copied.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property LengthCopied() As Long
      Get
        Return _lengthCopied
      End Get
      Set(ByVal value As Long)
        _lengthCopied = value
      End Set
    End Property
    Private _percent As Double
    ''' <summary>
    ''' Percent complete.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property Percent() As Double
      Get
        Return _percent
      End Get
      Set(ByVal value As Double)
        _percent = value
      End Set
    End Property
    Private _cancel As Boolean
    ''' <summary>
    ''' Cancels process.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property Cancel() As Boolean
      Get
        Return _cancel
      End Get
      Set(ByVal value As Boolean)
        _cancel = value
      End Set
    End Property

  End Class
End Namespace